<!DOCTYPE html>
<!-- saved from url=(0127)https://docs.google.com/document/d/e/2PACX-1vTyeM4564xsa6zmWVKwQHDT3aZLxgIj48gdVK5Pi0wuY8nvesvQGuDflxc-qRY685EqVFtxiZCSKc1c/pub -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>WebPerfWG call - June 4th 2020</title><link rel="shortcut icon" href="https://ssl.gstatic.com/docs/documents/images/kix-favicon7.ico"><meta name="referrer" content="strict-origin-when-cross-origin"><style type="text/css" nonce="">
      @import url("https://fonts.googleapis.com/css?family=Google+Sans");
      @import url("https://fonts.googleapis.com/css?family=Roboto");

      body {
        font-family: Roboto, arial, sans, sans-serif;
        margin: 0;
      }

      iframe {
        border: 0;
        frameborder: 0;
        height: 100%;
        width: 100%;
      }

      #header {
        align-items: center;
        background: white;
        border-bottom: 1px #ccc solid;
        display: flex;
        height: 60px;
        justify-content: space-between;
        position: fixed;
        top: 0;
        width: 100%;
        z-index: 100;
      }

      #header #title {
        font-family: 'Google Sans';
        font-size: large;
        margin: auto 0 auto 20px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        width: 70%;
      }

      #header #interval {
        margin: auto 25px auto 0;
        font-family: Roboto;
        font-size: small;;
      }

      #footer {
        background: #f0f0f0;
        border-bottom: 1px #ccc solid;
        bottom: 0;
        font-family: Roboto;
        font-size: small;
        padding: 10px 10px;
        position: fixed;
        text-align: center;
        width: 100%;
      }

      #contents {
        padding: 100px 20% 50px 20%;
      }

      @media only screen and (max-device-width: 800px) {
        #header {
          border-bottom-width: 5px;
          height: auto;
          display: block;
        }

        #header #title {
          font-size: 3em;
          margin: auto 0 auto 20px;
          width: 90%;
        }

        #header #interval {
          font-size: 1.5em;
          margin: 10px 0 auto 25px;
        }

        #contents {
          padding: 150px 5% 80px;
        }

        #footer {
          font-size: 2em;
        }
      }

      .dash {
        padding: 0 6px;
      }
    </style></head><body><div id="header"><div id="title">WebPerfWG call - June 4th 2020</div><div id="interval"><span></span></div></div><div id="contents"><style type="text/css">.lst-kix_418ua9khnd6l-8>li:before{content:"\0025a0  "}.lst-kix_418ua9khnd6l-4>li:before{content:"\0025cb  "}.lst-kix_418ua9khnd6l-3>li:before{content:"\0025cf  "}ul.lst-kix_418ua9khnd6l-0{list-style-type:none}.lst-kix_9e9sxe9mmk37-6>li:before{content:"\0025cf  "}ul.lst-kix_418ua9khnd6l-1{list-style-type:none}.lst-kix_9e9sxe9mmk37-5>li:before{content:"\0025a0  "}ul.lst-kix_418ua9khnd6l-4{list-style-type:none}.lst-kix_9e9sxe9mmk37-4>li:before{content:"\0025cb  "}ul.lst-kix_418ua9khnd6l-5{list-style-type:none}ul.lst-kix_418ua9khnd6l-2{list-style-type:none}ul.lst-kix_418ua9khnd6l-3{list-style-type:none}.lst-kix_418ua9khnd6l-5>li:before{content:"\0025a0  "}.lst-kix_9e9sxe9mmk37-2>li:before{content:"\0025a0  "}.lst-kix_9e9sxe9mmk37-3>li:before{content:"\0025cf  "}.lst-kix_418ua9khnd6l-6>li:before{content:"\0025cf  "}.lst-kix_418ua9khnd6l-7>li:before{content:"\0025cb  "}ul.lst-kix_9e9sxe9mmk37-8{list-style-type:none}.lst-kix_9e9sxe9mmk37-0>li:before{content:"\0025cf  "}.lst-kix_9e9sxe9mmk37-1>li:before{content:"\0025cb  "}ul.lst-kix_418ua9khnd6l-8{list-style-type:none}ul.lst-kix_418ua9khnd6l-6{list-style-type:none}ul.lst-kix_418ua9khnd6l-7{list-style-type:none}li.li-bullet-0:before{margin-left:-18pt;white-space:nowrap;display:inline-block;min-width:18pt}.lst-kix_418ua9khnd6l-1>li:before{content:"\0025cb  "}.lst-kix_418ua9khnd6l-0>li:before{content:"\0025cf  "}.lst-kix_418ua9khnd6l-2>li:before{content:"\0025a0  "}.lst-kix_9e9sxe9mmk37-7>li:before{content:"\0025cb  "}.lst-kix_9e9sxe9mmk37-8>li:before{content:"\0025a0  "}ul.lst-kix_9e9sxe9mmk37-1{list-style-type:none}ul.lst-kix_9e9sxe9mmk37-0{list-style-type:none}ul.lst-kix_9e9sxe9mmk37-3{list-style-type:none}ul.lst-kix_9e9sxe9mmk37-2{list-style-type:none}ul.lst-kix_9e9sxe9mmk37-5{list-style-type:none}ul.lst-kix_9e9sxe9mmk37-4{list-style-type:none}ul.lst-kix_9e9sxe9mmk37-7{list-style-type:none}ul.lst-kix_9e9sxe9mmk37-6{list-style-type:none}ol{margin:0;padding:0}table td,table th{padding:0}.c0{margin-left:36pt;padding-top:0pt;padding-left:0pt;padding-bottom:0pt;line-height:1.15;orphans:2;widows:2;text-align:left}.c11{padding-top:18pt;padding-bottom:6pt;line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}.c1{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:11pt;font-family:"Arial";font-style:normal}.c4{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:16pt;font-family:"Arial";font-style:normal}.c7{padding-top:0pt;padding-bottom:0pt;line-height:1.15;orphans:2;widows:2;text-align:left;height:11pt}.c8{color:#434343;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:14pt;font-family:"Arial";font-style:normal}.c13{padding-top:16pt;padding-bottom:4pt;line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}.c9{padding-top:0pt;padding-bottom:0pt;line-height:1.15;orphans:2;widows:2;text-align:left}.c10{text-decoration-skip-ink:none;-webkit-text-decoration-skip:none;color:#1155cc;text-decoration:underline}.c5{background-color:#ffffff;max-width:468pt;padding:72pt 72pt 72pt 72pt}.c12{margin-left:72pt;padding-left:0pt}.c3{padding:0;margin:0}.c6{color:inherit;text-decoration:inherit}.c2{font-weight:700}.title{padding-top:0pt;color:#000000;font-size:26pt;padding-bottom:3pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}.subtitle{padding-top:0pt;color:#666666;font-size:15pt;padding-bottom:16pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}li{color:#000000;font-size:11pt;font-family:"Arial"}p{margin:0;color:#000000;font-size:11pt;font-family:"Arial"}h1{padding-top:20pt;color:#000000;font-size:20pt;padding-bottom:6pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h2{padding-top:18pt;color:#000000;font-size:16pt;padding-bottom:6pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h3{padding-top:16pt;color:#434343;font-size:14pt;padding-bottom:4pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h4{padding-top:14pt;color:#666666;font-size:12pt;padding-bottom:4pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h5{padding-top:12pt;color:#666666;font-size:11pt;padding-bottom:4pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h6{padding-top:12pt;color:#666666;font-size:11pt;padding-bottom:4pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;font-style:italic;orphans:2;widows:2;text-align:left}</style><div class="c5"><h2 class="c11" id="h.7l5idrlvz4by"><span class="c4">Participants</span></h2><p class="c9"><span class="c1">Nic Jansma, Yoav Weiss, Benjamin De Kosnik, Gilles Dubuc, Peter Perl. Andy Davies, Michal Mocny, Nicol&aacute;s Pe&ntilde;a, Alex Christensen, Philip Walton, Annie Sullivan, Steven Bougon, Michelle Vu, Tom Maccabe, Ilya Grigorik, plh</span></p><h2 class="c11" id="h.u6emyj25g50r"><span class="c4">Next Meeting</span></h2><p class="c9"><span class="c1">June 18th @ 10am PST / 1pm EST</span></p><h2 class="c11" id="h.gptnk16ouuv4"><span class="c4">Presentations</span></h2><h3 class="c13" id="h.w88d32ks3g1s"><span class="c10"><a class="c6" href="https://www.google.com/url?q=https://docs.google.com/presentation/d/1_5i-xCcbdHI3rV8xuIOvChFIazef-jXSwsrfKEBsVjE/edit&amp;sa=D&amp;source=editors&amp;ust=1613234400782000&amp;usg=AOvVaw1NA-hdtixoKDcA7S3V1iSW">Web Vitals</a></span></h3><p class="c9"><span class="c2">Ilya</span><span class="c1"><b></b>: What is Web Vitals?</span></p><ul class="c3 lst-kix_418ua9khnd6l-0 start"><li class="c0 li-bullet-0"><span class="c1">Announced a few weeks back. A program with multiple components:</span></li><li class="c0 li-bullet-0"><span class="c1">We’ve been evangelizing web performance, but there are too many tools and metrics.</span></li><li class="c0 li-bullet-0"><span class="c1">Google is committing to make the tools more coherent, focusing on a small set of metrics</span></li><li class="c0 li-bullet-0"><span class="c1">Providing more predictable cadence, so the ecosystem can know when key metrics are likely to change - Core Web Vitals</span></li><li class="c0 li-bullet-0"><span class="c1">Roughly annual update cycle</span></li><li class="c0 li-bullet-0"><span class="c1">For 2020, we focused on 3 metrics: LCP, FID and CLS</span></li><li class="c0 li-bullet-0"><span class="c1">Also providing guidance on good, need improvement and poor experiences / thresholds</span></li><li class="c0 li-bullet-0"><span class="c1">We wrote down how we arrived at these thresholds, based on research and feasibility - couldn’t start out too aggressive, but that might change in the future</span></li><li class="c0 li-bullet-0"><span class="c1"><b>Created a lot of content to educate folks</b>: web.dev/webvitals</span></li><li class="c0 li-bullet-0"><span class="c1">Last week, Search announced that they’re evaluating page experience as part of ranking</span></li><li class="c0 li-bullet-0"><span class="c1">That’s not new in itself, but unifying CWV as the metrics for that is</span></li><li class="c0 li-bullet-0"><span class="c1"><b>Strong push to unify all the tools</b>: PSI, CRUX, SC, Dev Tools, Lighthouse &amp; Web Vitals extension</span></li><li class="c0 li-bullet-0"><span class="c1">Philip open-sources web-vitals.js to collect those metrics, which includes all the best practices for collection</span></li></ul><ul class="c3 lst-kix_418ua9khnd6l-1 start"><li class="c9 c12 li-bullet-0"><span class="c1">Encourage everyone to look into the implementation</span></li></ul><ul class="c3 lst-kix_418ua9khnd6l-0"><li class="c0 li-bullet-0"><span class="c1">What about WebVitals 2021?</span></li><li class="c0 li-bullet-0"><span style="overflow: hidden;<b> display</b>: inline-block;<b> margin</b>: 0.00px 0.00px;<b> border</b>: 0.00px solid #000000;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);<b> width</b>: 624.00px;<b> height</b>: 350.67px;"><img alt="" src="./index_files/Screenshot 2020-06-04 at 19.13.45.png" style="width: 624.00px;<b> height</b>: 350.67px; margin-left: 0.00px; margin-top: 0.00px;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span></li><li class="c0 li-bullet-0"><span class="c1">SPA are a common theme where current metrics lack</span></li><li class="c0 li-bullet-0"><span class="c1">FID is great, but we care about responsiveness in general and all input</span></li><li class="c0 li-bullet-0"><span class="c1">CLS actually captures complete coverage, but creates other challenges: long lived pages are penalized. Maybe we can normalize it?</span></li><li class="c0 li-bullet-0"><span style="overflow: hidden;<b> display</b>: inline-block;<b> margin</b>: 0.00px 0.00px;<b> border</b>: 0.00px solid #000000;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);<b> width</b>: 624.00px;<b> height</b>: 333.33px;"><img alt="" src="./index_files/Screenshot 2020-06-04 at 19.16.05.png" style="width: 624.00px;<b> height</b>: 333.33px; margin-left: 0.00px; margin-top: 0.00px;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span></li><li class="c0 li-bullet-0"><span class="c1">Frame Timing, Event Timing, normalization are potential answers</span></li><li class="c0 li-bullet-0"><span class="c1">Would be great to get consensus on how to present metrics in different performance tools</span></li><li class="c0 li-bullet-0"><span class="c1">SPA are lacking a standard API for page transitions, which makes it hard for e.g. CRUX to collect that data. Some telemetry may look worse because of an SPA and we don't want to dis-incentivize from our metrics.</span></li><li class="c0 li-bullet-0"><span class="c1">Priorities</span></li><li class="c0 li-bullet-0"><span style="overflow: hidden;<b> display</b>: inline-block;<b> margin</b>: 0.00px 0.00px;<b> border</b>: 0.00px solid #000000;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);<b> width</b>: 624.00px;<b> height</b>: 320.00px;"><img alt="" src="./index_files/Screenshot 2020-06-04 at 19.18.34.png" style="width: 624.00px;<b> height</b>: 320.00px; margin-left: 0.00px; margin-top: 0.00px;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span></li><li class="c0 li-bullet-0"><span class="c1">Questions?</span></li><li class="c0 li-bullet-0"><span class="c2">Steven</span><span class="c1"><b></b>: For us SPAs are the most important one. Seems like you ditched TTI for Input Delay. Why?</span></li><li class="c0 li-bullet-0"><span class="c2">Annie</span><span class="c1"><b></b>: TTI can be used in both lab and field. In the field, TTI can take a long time to complete, the user may leave the page before it completes - abort bias</span></li><li class="c0 li-bullet-0"><span class="c1">... FID gives us more direct measure of UX</span></li><li class="c0 li-bullet-0"><span class="c2">Steven</span><span class="c1"><b></b>: But FID depends on user behavior, how can we detect regressions in the lab?</span></li><li class="c0 li-bullet-0"><span class="c2">Annie</span><span class="c1"><b></b>: Compared approached to a lab metric - Total Blocking Time was highly correlated</span></li><li class="c0 li-bullet-0"><span class="c1">... I think Wikipedia did something similar</span></li><li class="c0 li-bullet-0"><span class="c2">Michal</span><span class="c1"><b></b>: TBT is defined in terms of TTI, so it gives you a measurement of how busy the page was before it stopped loading. More elasitc</span></li><li class="c0 li-bullet-0"><span class="c2">Annie</span><span class="c1"><b></b>: We have studies on that, I can share in the chat</span></li><li class="c0 li-bullet-0"><span class="c1">... TBT is bounded by TTI, but is much more elastic</span></li></ul><h2 class="c11" id="h.t0o22mym9v3d"><span>&nbsp;</span><span class="c10"><a class="c6" href="https://www.google.com/url?q=https://docs.google.com/presentation/d/1xYpHsK6LDhEZZPRkKChn3wKjmHwN3ecCpdAdks6j_QU/&amp;sa=D&amp;source=editors&amp;ust=1613234400786000&amp;usg=AOvVaw042MWfoeiNNeVQBmGhgU9S">Interactions, normalization and SPA Navs</a></span></h2><ul class="c3 lst-kix_418ua9khnd6l-0"><li class="c0 li-bullet-0"><span class="c2">Michal</span><span class="c1"><b></b>: We want to move from tracking input delay to responsiveness in general</span></li><li class="c0 li-bullet-0"><span class="c1">Not just first input, but all input</span></li><li class="c0 li-bullet-0"><span style="overflow: hidden;<b> display</b>: inline-block;<b> margin</b>: 0.00px 0.00px;<b> border</b>: 0.00px solid #000000;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);<b> width</b>: 624.00px;<b> height</b>: 348.00px;"><img alt="" src="./index_files/Screenshot 2020-06-04 at 19.24.19.png" style="width: 624.00px;<b> height</b>: 348.00px; margin-left: 0.00px; margin-top: 0.00px;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span></li><li class="c0 li-bullet-0"><span class="c1">Event Timing gives us input responsiveness, but cannot handle async work that results from the event</span></li><li class="c0 li-bullet-0"><span class="c1">Resource fetches, API calls, queued tasks</span></li><li class="c0 li-bullet-0"><span class="c1">Event Timing shipping in Chrome 85</span></li><li class="c0 li-bullet-0"><span class="c1">Also exploring heuristics for async tasks</span></li></ul><ul class="c3 lst-kix_418ua9khnd6l-1 start"><li class="c9 c12 li-bullet-0"><span class="c1">Resource fetches, XHR, scheduled tasks</span></li><li class="c9 c12 li-bullet-0"><span class="c1">Can paints be attributed to tasks?</span></li></ul><ul class="c3 lst-kix_418ua9khnd6l-0"><li class="c0 li-bullet-0"><span class="c1">Normalization</span></li><li class="c0 li-bullet-0"><span class="c1">As we cover more of the page lifecycle, we don’t want the most interacted with pages to be judged to be worse</span></li><li class="c0 li-bullet-0"><span class="c1"><b>Options</b>: sum of all durations, average, max?</span></li><li class="c0 li-bullet-0"><span class="c1">CLS already has some of these problems</span></li><li class="c0 li-bullet-0"><span class="c1">Long lived sessions with repeated shifts may have large scores</span></li><li class="c0 li-bullet-0"><span class="c1">Maybe separate CLS scores for each section?</span></li><li class="c0 li-bullet-0"><span class="c1">Adjusted vs, non-adjusted - similar to long tasks, maybe we can define a budget for each interaction and count things that surpass budget</span></li><li class="c0 li-bullet-0"><span class="c1">Per page load/ per session</span></li><li class="c0 li-bullet-0"><span class="c1">Important to consider SPA routes, and match metrics to specific routes</span></li><li class="c0 li-bullet-0"><span class="c1">Goal is to have accurate heuristics</span></li><li class="c0 li-bullet-0"><span class="c1">Need real world data</span></li><li class="c0 li-bullet-0"><span class="c1">Want to start with annotation by frameworks</span></li><li class="c0 li-bullet-0"><span class="c1">Can leverage user timing without changing the spec/implementations using a convention</span></li><li class="c0 li-bullet-0"><span class="c1">Use "detail" field to add a navigation attribute</span></li><li class="c0 li-bullet-0"><span class="c1">Considering passing a Promise to signal the end of a navigation, to measure things during the transition</span></li></ul><ul class="c3 lst-kix_418ua9khnd6l-1 start"><li class="c9 c12 li-bullet-0"><span class="c1">Not yet proposals, but considering</span></li></ul><ul class="c3 lst-kix_418ua9khnd6l-0"><li class="c0 li-bullet-0"><span class="c1">How do we add this to frameworks?</span></li><li class="c0 li-bullet-0"><span class="c1">Usually easy to track start, but automatic end conditions are hard</span></li><li class="c0 li-bullet-0"><span class="c1">An approach similar to TTI can help us to know the page is idle</span></li><li class="c0 li-bullet-0"><span class="c1">Questions?</span></li><li class="c0 li-bullet-0"><span class="c2">Steven</span><span class="c1"><b></b>: if we add an API for SPA navigation that resets all the metrics, would that cover most of the use cases? Routing frameworks would call it</span></li><li class="c0 li-bullet-0"><span class="c2">Michal</span><span class="c1"><b></b>: Worried about how we’re introducing it. With SPAs there are partial loads, so it’s harder to naively reset paint timing.</span></li><li class="c0 li-bullet-0"><span class="c1">... If we rely on developer hints on resetting time, it can introduce bias</span></li><li class="c0 li-bullet-0"><span class="c1">... We want to capture user experience. So want the hints to inform the metrics</span></li><li class="c0 li-bullet-0"><span class="c2">Nic</span><span class="c1"><b></b>: You were talking about offering a way to measure, 3P analytics want to know when things are starting. So having a way to hint at the beginning can be great for 3P analytics</span></li><li class="c0 li-bullet-0"><span class="c1">... We’re looking at the network. Can also be interesting to look at visual input. Akamai’s approach doesn’t always get it right in complex pages</span></li><li class="c0 li-bullet-0"><span class="c1">... Not sure if the browser can know more, or if the developer needs to annotate</span></li><li class="c0 li-bullet-0"><span class="c1">... Would be great to do smarter things automatically</span></li><li class="c0 li-bullet-0"><span class="c2">Michal</span><span class="c1"><b></b>: If we have good metrics that give us a best guess</span></li><li class="c0 li-bullet-0"><span class="c1">Reporting at the end has issues with abandonment</span></li><li class="c0 li-bullet-0"><span class="c1">Reporting at the beginning and updating at the end will have issues with the UserTiming API as it is now</span></li><li class="c0 li-bullet-0"><span class="c2">Benjamin</span><span class="c1"><b></b>: Should implementers and developers think of this as a separate and distinct from page navigation?</span></li><li class="c0 li-bullet-0"><span class="c1">Second question is for implementors to do the same thing?</span></li><li class="c0 li-bullet-0"><span class="c2">Michal</span><span class="c1"><b></b>: We’re not currently thinking of resetting metrics</span></li><li class="c0 li-bullet-0"><span class="c1">... But important to be able to aggregate normally.</span></li><li class="c0 li-bullet-0"><span class="c1">... Because SPAs have page transition it’s not trivial to reset metrics</span></li><li class="c0 li-bullet-0"><span class="c2">Benjamin</span><span class="c1"><b></b>: Previously undecided in the group, but I tend to agree</span></li></ul><p class="c7"><span class="c1"></span></p><h3 class="c13" id="h.wfz7xus4l5q8"><span class="c10"><a class="c6" href="https://www.google.com/url?q=https://docs.google.com/presentation/d/1YBflXs_zvJkL6bD6LIhlS3p1AkNpJWYioFMyFdfjf7Y&amp;sa=D&amp;source=editors&amp;ust=1613234400795000&amp;usg=AOvVaw16XPN3oA-x0lVjmLG1iNJi">Measuring smoothness on the web</a></span></h3><ul class="c3 lst-kix_418ua9khnd6l-0"><li class="c0 li-bullet-0"><span class="c2">Michal</span><span class="c1"><b></b>: *presenting*</span></li><li class="c0 li-bullet-0"><span class="c1"><b>Goal</b>: track smoothness of scrolling and animations</span></li><li class="c0 li-bullet-0"><span class="c1">Number of dropped frames, variation between frames, stale frames</span></li><li class="c0 li-bullet-0"><span class="c1">Old Frame Timing API was more about the event loop and frames that exceeded time budgets. This is a higher level API</span></li><li class="c0 li-bullet-0"><span class="c1">Two different cases among dropped frames that we need to address</span></li><li class="c0 li-bullet-0"><span style="overflow: hidden;<b> display</b>: inline-block;<b> margin</b>: 0.00px 0.00px;<b> border</b>: 0.00px solid #000000;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);<b> width</b>: 624.00px;<b> height</b>: 352.00px;"><img alt="" src="./index_files/Screenshot 2020-06-04 at 19.43.42.png" style="width: 624.00px;<b> height</b>: 352.00px; margin-left: 0.00px; margin-top: 0.00px;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span></li><li class="c0 li-bullet-0"><span class="c1">Same number of dropped frames, but different user experiences</span></li><li class="c0 li-bullet-0"><span class="c1">Sometimes, dropped frames are not an issue, because there’s nothing to show</span></li><li class="c0 li-bullet-0"><span class="c1">API proposal</span></li><li class="c0 li-bullet-0"><span style="overflow: hidden;<b> display</b>: inline-block;<b> margin</b>: 0.00px 0.00px;<b> border</b>: 0.00px solid #000000;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);<b> width</b>: 624.00px;<b> height</b>: 349.33px;"><img alt="" src="./index_files/Screenshot 2020-06-04 at 19.45.26.png" style="width: 624.00px;<b> height</b>: 349.33px; margin-left: 0.00px; margin-top: 0.00px;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span></li><li class="c0 li-bullet-0"><span class="c1">Entries contain refresh rate, attribution data and a list of frames.</span></li><li class="c0 li-bullet-0"><span class="c10"><a class="c6" href="https://www.google.com/url?q=https://docs.google.com/document/d/1t3A56iTN01ReEELJ18_jLYrvc13L3hDTXWK46AafKwE/edit%23&amp;sa=D&amp;source=editors&amp;ust=1613234400797000&amp;usg=AOvVaw27wCZj1Gkpfhpr0mNzY1I1">Links to detailed proposal</a></span></li><li class="c0 li-bullet-0"><span class="c1">Example usage:</span></li><li class="c0 li-bullet-0"><span style="overflow: hidden;<b> display</b>: inline-block;<b> margin</b>: 0.00px 0.00px;<b> border</b>: 0.00px solid #000000;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);<b> width</b>: 624.00px;<b> height</b>: 353.33px;"><img alt="" src="./index_files/pasted image 0.png" style="width: 624.00px;<b> height</b>: 353.33px; margin-left: 0.00px; margin-top: 0.00px;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span></li><li class="c0 li-bullet-0"><span class="c1">Potential extensions to that:</span></li></ul><ul class="c3 lst-kix_418ua9khnd6l-1 start"><li class="c9 c12 li-bullet-0"><span class="c1">Support custom recordings</span></li><li class="c9 c12 li-bullet-0"><span class="c1">Add attribution to make it more actionable</span></li></ul><ul class="c3 lst-kix_418ua9khnd6l-0"><li class="c0 li-bullet-0"><span class="c1">Questions?</span></li><li class="c0 li-bullet-0"><span class="c2">Nic</span><span class="c1"><b></b>: I like attribution out the gate</span></li><li class="c0 li-bullet-0"><span class="c2">Michal</span><span class="c1"><b></b>: It’s still early but want folks to look at it</span></li><li class="c0 li-bullet-0"><span class="c2">Gilles</span><span class="c1"><b></b>: For previous APIs, the buffered flag were in the 100s. Here we’d only have a few seconds</span></li><li class="c0 li-bullet-0"><span class="c2">Michal</span><span class="c1"><b></b>: You don’t get one entry per frame, but an entry per animation</span></li><li class="c0 li-bullet-0"><span class="c1">... How would we report things with very long lifelines? Maybe entry every few seconds?</span></li><li class="c0 li-bullet-0"><span class="c1">... But shouldn’t have too many entries</span></li><li class="c0 li-bullet-0"><span class="c2">Ilya</span><span class="c1"><b></b>: How would scrolling be manifested in the timeline?</span></li><li class="c0 li-bullet-0"><span class="c2">Michal</span><span class="c1"><b></b>: At the end of the scroll you’d get an entry with a subtype of “scroll”, and more details per frame in the list of frames</span></li><li class="c0 li-bullet-0"><span class="c1">Unlike the previous proposal, things like scroll can be handled on the compositor, so scrolls can run even when the main frame is blocked</span></li><li class="c0 li-bullet-0"><span class="c1">A whole bunch of animations having at a different pace, like rAF vs scroll, etc</span></li><li class="c0 li-bullet-0"><span class="c2">Ilya</span><span class="c1"><b></b>: Would we want to emit these for every animation? Or only for bad ones?</span></li><li class="c0 li-bullet-0"><span class="c2">Michal</span><span class="c1"><b></b>: The proposal is for everything, but it’s an interesting question</span></li><li class="c0 li-bullet-0"><span class="c1">... Do we want to confirm everything is going well? Important to track surprises?</span></li><li class="c0 li-bullet-0"><span class="c2">Ilya</span><span class="c1"><b></b>: One consideration, What’s the overhead of measuring this? For LT, we only surface the bad stuff, so hard to understand the ratio of good to bad tasks.</span></li><li class="c0 li-bullet-0"><span class="c2">Michal</span><span class="c1"><b></b>: No intuition yet on the overhead</span></li><li class="c0 li-bullet-0"><span class="c2">Nicol&aacute;s</span><span class="c1"><b></b>: The overhead is not just with graphics, as you’d be accumulating JS objects. Maybe we can use counts, like we do in EventTiming, and avoid emitting the good animations</span></li><li class="c0 li-bullet-0"><span class="c2">Ilya:</span><span class="c1">&nbsp;Ben and Alex - thoughts?</span></li><li class="c0 li-bullet-0"><span class="c2">Alex</span><span class="c1"><b></b>: Already expressed my concerns about async scrolling and overhead</span></li><li class="c0 li-bullet-0"><span class="c2">Ilya</span><span class="c1"><b></b>: We can get more data on that and come back</span></li><li class="c0 li-bullet-0"><span class="c2">Ilya</span><span class="c1"><b></b>: What’s the plan for Frame Timing? Resurrect that? &nbsp;New proposal?</span></li><li class="c0 li-bullet-0"><span class="c2">Michal</span><span class="c1"><b></b>: Decided to file the issues in the original repo, and this is related enough. OTOH, it’s rather different. Should we keep it in the same repo or move it elsewhere?</span></li><li class="c0 li-bullet-0"><span class="c2">Ilya</span><span class="c1"><b></b>: Would we still call it Frame Timing?</span></li><li class="c0 li-bullet-0"><span class="c2">Michal</span><span class="c1"><b></b>: Good question</span></li><li class="c0 li-bullet-0"><span class="c1">... Frame Timing for scrolls and animations</span></li><li class="c0 li-bullet-0"><span class="c2">Ilya:</span><span class="c1">&nbsp;If we are using Frame Timing, just making sure we point people at the latest proposal and not getting buried in the old discussions</span></li><li class="c0 li-bullet-0"><span class="c2">Yoav:</span><span class="c1">&nbsp;Because the word frame is so overloaded (iframes, etc) and since this focuses on animation, maybe its worthwhile to rename to AnimationTiming (as a means to measure smoothness)</span></li><li class="c0 li-bullet-0"><span class="c2">Alex</span><span class="c1"><b></b>: Not sure if that’ll allow you to see across origins</span></li><li class="c0 li-bullet-0"><span class="c2">Michal</span><span class="c1"><b></b>: We’ll want to cover security implications more deeply</span></li><li class="c0 li-bullet-0"><span class="c2">Alex</span><span class="c1"><b></b>: Can also indicate things about the user’s system, e.g. compiling in the background</span></li></ul></div></div><div id="footer"><span>Published by <a target="_blank" title="Learn more about Google Drive" href="https://docs.google.com/">Google Drive</a></span><span class="dash">–</span><a href="https://docs.google.com/u/0/abuse?id=AKkXjoyqPePJDLo22aH1NAVVQw1FpGrv58_WnVf6bcVgyphCevyerm-yJhUS3FC-wkKDtCbJK9Wp4Y2JEQ8kpu4:0">Report Abuse</a></div><script type="text/javascript" nonce="">(function(){/*

 Copyright The Closure Library Authors.
 SPDX-License-Identifier: Apache-2.0
*/
var aa="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(a==Array.prototype||a==Object.prototype)return a;a[b]=c.value;return a};function ba(a){a=["object"==typeof globalThis&&globalThis,a,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var b=0;b<a.length;++b){var c=a[b];if(c&&c.Math==Math)return c}throw Error("Cannot find global object");}var ca=ba(this);
function da(a,b){if(b)a:{var c=ca;a=a.split(".");for(var d=0;d<a.length-1;d++){var e=a[d];if(!(e in c))break a;c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&aa(c,a,{configurable:!0,writable:!0,value:b})}}var ea="function"==typeof Object.create?Object.create:function(a){function b(){}b.prototype=a;return new b},fa;
if("function"==typeof Object.setPrototypeOf)fa=Object.setPrototypeOf;else{var ha;a:{var ia={a:!0},ja={};try{ja.__proto__=ia;ha=ja.a;break a}catch(a){}ha=!1}fa=ha?function(a,b){a.__proto__=b;if(a.__proto__!==b)throw new TypeError(a+" is not extensible");return a}:null}var ka=fa;
function h(a,b){a.prototype=ea(b.prototype);a.prototype.constructor=a;if(ka)ka(a,b);else for(var c in b)if("prototype"!=c)if(Object.defineProperties){var d=Object.getOwnPropertyDescriptor(b,c);d&&Object.defineProperty(a,c,d)}else a[c]=b[c];a.o=b.prototype}da("Object.is",function(a){return a?a:function(b,c){return b===c?0!==b||1/b===1/c:b!==b&&c!==c}});var l=this||self;function la(){}function ma(a){var b=typeof a;return"object"==b&&null!=a||"function"==b}
function na(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var d=c.slice();d.push.apply(d,arguments);return a.apply(this,d)}}function oa(a,b){function c(){}c.prototype=b.prototype;a.o=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.B=function(d,e,f){for(var g=Array(arguments.length-2),k=2;k<arguments.length;k++)g[k-2]=arguments[k];return b.prototype[e].apply(d,g)}}function pa(a){return a};var qa=Array.prototype.indexOf?function(a,b){return Array.prototype.indexOf.call(a,b,void 0)}:function(a,b){if("string"===typeof a)return"string"!==typeof b||1!=b.length?-1:a.indexOf(b,0);for(var c=0;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1};function ra(a,b,c){for(var d in a)b.call(c,a[d],d,a)};var m;function p(a,b){this.i=a===sa&&b||"";this.j=ta}p.prototype.h=!0;p.prototype.g=function(){return this.i};var ta={},sa={};var ua=String.prototype.trim?function(a){return a.trim()}:function(a){return/^[\s\xa0]*([\s\S]*?)[\s\xa0]*$/.exec(a)[1]},va=/&/g,wa=/</g,xa=/>/g,ya=/"/g,za=/'/g,Aa=/\x00/g,Ba=/[\x00&<>"']/;function Ca(a,b){return a<b?-1:a>b?1:0};function q(a,b){this.i=b===r?a:""}q.prototype.h=!0;q.prototype.g=function(){return this.i.toString()};q.prototype.toString=function(){return this.i.toString()};function u(a){return a instanceof q&&a.constructor===q?a.i:"type_error:SafeUrl"}
var Da=/^(?:audio\/(?:3gpp2|3gpp|aac|L16|midi|mp3|mp4|mpeg|oga|ogg|opus|x-m4a|x-matroska|x-wav|wav|webm)|font\/\w+|image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp|x-icon)|video\/(?:mpeg|mp4|ogg|webm|quicktime|x-matroska))(?:;\w+=(?:\w+|"[\w;,= ]+"))*$/i,Ea=/^data:(.*);base64,[a-z0-9+\/]+=*$/i,Fa=/^(?:(?:https?|mailto|ftp):|[^:/?#]*(?:[/?#]|$))/i;function Ga(a){if(a instanceof q)return a;a="object"==typeof a&&a.h?a.g():String(a);Fa.test(a)||(a="about:invalid#zClosurez");return new q(a,r)}
var r={},Ha=new q("about:invalid#zClosurez",r);var v;a:{var Ia=l.navigator;if(Ia){var Ja=Ia.userAgent;if(Ja){v=Ja;break a}}v=""}function w(a){return-1!=v.indexOf(a)};function x(a,b,c){this.i=c===Ka?a:""}x.prototype.h=!0;x.prototype.g=function(){return this.i.toString()};x.prototype.toString=function(){return this.i.toString()};var Ka={};function La(a,b,c,d){a=a instanceof q?a:Ga(a);b=b||l;c=c instanceof p?c instanceof p&&c.constructor===p&&c.j===ta?c.i:"type_error:Const":c||"";return void 0!==d?b.open(u(a),c,d,void 0):b.open(u(a),c)};function Ma(a){Ma[" "](a);return a}Ma[" "]=la;function y(a,b,c){return Object.prototype.hasOwnProperty.call(a,b)?a[b]:a[b]=c(b)};var Na=w("Opera"),z=w("Trident")||w("MSIE"),Oa=w("Edge"),Pa=Oa||z,Qa=w("Gecko")&&!(-1!=v.toLowerCase().indexOf("webkit")&&!w("Edge"))&&!(w("Trident")||w("MSIE"))&&!w("Edge"),Ra=-1!=v.toLowerCase().indexOf("webkit")&&!w("Edge"),Sa=w("Macintosh");function Ta(){var a=l.document;return a?a.documentMode:void 0}var Ua;
a:{var Va="",Wa=function(){var a=v;if(Qa)return/rv:([^\);]+)(\)|;)/.exec(a);if(Oa)return/Edge\/([\d\.]+)/.exec(a);if(z)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(a);if(Ra)return/WebKit\/(\S+)/.exec(a);if(Na)return/(?:Version)[ \/]?(\S+)/.exec(a)}();Wa&&(Va=Wa?Wa[1]:"");if(z){var Xa=Ta();if(null!=Xa&&Xa>parseFloat(Va)){Ua=String(Xa);break a}}Ua=Va}var Ya=Ua,Za={},$a;if(l.document&&z){var ab=Ta();$a=ab?ab:parseInt(Ya,10)||void 0}else $a=void 0;var bb=$a;function cb(a){return y(a.prototype,"$$generatedClassName",function(){return"Class$obf_"+{valueOf:function(){return++db}}})}var db=1E3;function A(){}A.prototype.u=function(){return this.j||(Object.defineProperties(this,{j:{value:++eb,enumerable:!1}}),this.j)};A.prototype.toString=function(){var a=B(fb(gb(this.constructor)))+"@";var b=(this.u()>>>0).toString(16);return a+B(b)};function D(){}h(D,A);D.prototype.i=function(a){this.h=a;if(a instanceof Object)try{a.A=this}catch(b){}};function hb(a){a.h instanceof Error&&(Error.captureStackTrace?Error.captureStackTrace(a.h):a.h.stack=Error().stack)}D.prototype.toString=function(){var a=fb(gb(this.constructor)),b=this.l;return null==b?a:B(a)+": "+B(b)};function ib(){}h(ib,D);function jb(){}h(jb,ib);var eb=0;function E(){}h(E,jb);E.prototype.i=function(a){jb.prototype.i.call(this,Object.is(this.g,"__noinit__")?a:this.g)};function kb(){}h(kb,E);function lb(a,b){return"string"==typeof a?a.charCodeAt(b):a.g(b)};function B(a){return null==a?"null":a.toString()}function mb(a){return 65536<=a?B(String.fromCharCode((55296+((a-65536|0)>>10&1023)|0)&65535))+B(String.fromCharCode((56320+((a-65536|0)&1023)|0)&65535)):String.fromCharCode(a&65535)}function nb(a,b){var c=b,d=a.length,e;b=lb(a,(e=c,c=c+1|0,e));var f;if(e=55296<=b&&56319>=b&&c<d)a=f=lb(a,c),e=56320<=a&&57343>=a;var g;e?g=65536+((b&1023)<<10)+(f&1023)|0:g=b;return g};function ob(a,b){this.h=a;this.g=b}h(ob,A);function fb(a){var b=cb(a.h);0!=a.g&&(b="L"+B(b)+";");a=a.g;for(var c="",d=0;d<a;d=d+1|0)c=B(c)+"[";return B(c)+B(b)}ob.prototype.toString=function(){return"class "+B(fb(this))};function gb(a){var b=0;return y(a.prototype,"$$class/"+b,function(){return new ob(a,b)})};function pb(a,b){return null==a?a:b?decodeURI(a):decodeURIComponent(a)};var qb=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#([\S\s]*))?$/;function rb(a){a=qb.exec(a);for(var b=[],c=0;7>=c;c=c+1|0)a.length<=c||null==a[c]?b.push(null):b.push(a[c]);return b}
function sb(a,b){var c=a.indexOf(mb(35));c=0>c?a.length:c;a:{var d=0;for(var e=b.length;0<(d=a.indexOf(b,d))&&d<c;){var f=nb(a,d-1|0);if(38==f||63==f){if((d+e|0)>=a.length)break a;f=nb(a,d+e|0);if(61==f||38==f||35==f)break a}d=d+(e+1)|0}d=-1}if(0>d)return null;e=a.indexOf(mb(38),d);if(0>e||e>c)e=c;d=d+(b.length+1)|0;b=Math.min(a.length,d);a=a.substr(b,Math.min(a.length,Math.max(d,e))-b|0);c=" ";for(b=0;0<=(b=c.indexOf("\\",b));)36==c.charCodeAt(b+1|0)?(d=B(c.substr(0,b|0))+"$",e=b=b+1|0,c=d+B(c.substr(e))):
(d=B(c.substr(0,b|0)),e=b=b+1|0,c=d+B(c.substr(e)));a=a.replace(/\+/g,c);return pb(a,!1)};function F(a,b){this.h=b;for(var c=[],d=!0,e=a.length-1;0<=e;e--){var f=a[e]|0;d&&f==b||(c[e]=f,d=!1)}this.g=c}var tb={};function ub(a){return-128<=a&&128>a?y(tb,a,function(b){return new F([b|0],0>b?-1:0)}):new F([a|0],0>a?-1:0)}function G(a){if(isNaN(a)||!isFinite(a))return H;if(0>a)return I(G(-a));for(var b=[],c=1,d=0;a>=c;d++)b[d]=a/c|0,c*=4294967296;return new F(b,0)}var H=ub(0),J=ub(1),vb=ub(16777216);
function K(a){if(-1==a.h)return-K(I(a));for(var b=0,c=1,d=0;d<a.g.length;d++){var e=L(a,d);b+=(0<=e?e:4294967296+e)*c;c*=4294967296}return b}F.prototype.toString=function(a){a=a||10;if(2>a||36<a)throw Error("radix out of range: "+a);if(M(this))return"0";if(-1==this.h)return"-"+I(this).toString(a);for(var b=G(Math.pow(a,6)),c=this,d="";;){var e=wb(c,b).g;c=N(c,O(e,b));var f=((0<c.g.length?c.g[0]:c.h)>>>0).toString(a);c=e;if(M(c))return f+d;for(;6>f.length;)f="0"+f;d=f+d}};
function L(a,b){return 0>b?0:b<a.g.length?a.g[b]:a.h}function M(a){if(0!=a.h)return!1;for(var b=0;b<a.g.length;b++)if(0!=a.g[b])return!1;return!0}function P(a,b){a=N(a,b);return-1==a.h?-1:M(a)?0:1}function I(a){for(var b=a.g.length,c=[],d=0;d<b;d++)c[d]=~a.g[d];return(new F(c,~a.h)).add(J)}F.prototype.abs=function(){return-1==this.h?I(this):this};
F.prototype.add=function(a){for(var b=Math.max(this.g.length,a.g.length),c=[],d=0,e=0;e<=b;e++){var f=d+(L(this,e)&65535)+(L(a,e)&65535),g=(f>>>16)+(L(this,e)>>>16)+(L(a,e)>>>16);d=g>>>16;f&=65535;g&=65535;c[e]=g<<16|f}return new F(c,c[c.length-1]&-2147483648?-1:0)};function N(a,b){return a.add(I(b))}
function O(a,b){if(M(a)||M(b))return H;if(-1==a.h)return-1==b.h?O(I(a),I(b)):I(O(I(a),b));if(-1==b.h)return I(O(a,I(b)));if(0>P(a,vb)&&0>P(b,vb))return G(K(a)*K(b));for(var c=a.g.length+b.g.length,d=[],e=0;e<2*c;e++)d[e]=0;for(e=0;e<a.g.length;e++)for(var f=0;f<b.g.length;f++){var g=L(a,e)>>>16,k=L(a,e)&65535,t=L(b,f)>>>16,n=L(b,f)&65535;d[2*e+2*f]+=k*n;Q(d,2*e+2*f);d[2*e+2*f+1]+=g*n;Q(d,2*e+2*f+1);d[2*e+2*f+1]+=k*t;Q(d,2*e+2*f+1);d[2*e+2*f+2]+=g*t;Q(d,2*e+2*f+2)}for(e=0;e<c;e++)d[e]=d[2*e+1]<<16|
d[2*e];for(e=c;e<2*c;e++)d[e]=0;return new F(d,0)}function Q(a,b){for(;(a[b]&65535)!=a[b];)a[b+1]+=a[b]>>>16,a[b]&=65535,b++}function S(a,b){this.g=a;this.h=b}
function wb(a,b){if(M(b))throw Error("division by zero");if(M(a))return new S(H,H);if(-1==a.h)return b=wb(I(a),b),new S(I(b.g),I(b.h));if(-1==b.h)return b=wb(a,I(b)),new S(I(b.g),b.h);if(30<a.g.length){if(-1==a.h||-1==b.h)throw Error("slowDivide_ only works with positive integers.");for(var c=J,d=b;0>=P(d,a);)c=xb(c,1),d=xb(d,1);var e=T(c,1),f=T(d,1);d=T(d,2);for(c=T(c,2);!M(d);){var g=f.add(d);0>=P(g,a)&&(e=e.add(c),f=g);d=T(d,1);c=T(c,1)}b=N(a,O(e,b));return new S(e,b)}for(e=H;0<=P(a,b);){c=Math.max(1,
Math.floor(K(a)/K(b)));d=Math.ceil(Math.log(c)/Math.LN2);d=48>=d?1:Math.pow(2,d-48);f=G(c);for(g=O(f,b);-1==g.h||0<P(g,a);)c-=d,f=G(c),g=O(f,b);M(f)&&(f=J);e=e.add(f);a=N(a,g)}return new S(e,a)}F.prototype.and=function(a){for(var b=Math.max(this.g.length,a.g.length),c=[],d=0;d<b;d++)c[d]=L(this,d)&L(a,d);return new F(c,this.h&a.h)};F.prototype.or=function(a){for(var b=Math.max(this.g.length,a.g.length),c=[],d=0;d<b;d++)c[d]=L(this,d)|L(a,d);return new F(c,this.h|a.h)};
F.prototype.xor=function(a){for(var b=Math.max(this.g.length,a.g.length),c=[],d=0;d<b;d++)c[d]=L(this,d)^L(a,d);return new F(c,this.h^a.h)};function xb(a,b){var c=b>>5;b%=32;for(var d=a.g.length+c+(0<b?1:0),e=[],f=0;f<d;f++)e[f]=0<b?L(a,f-c)<<b|L(a,f-c-1)>>>32-b:L(a,f-c);return new F(e,a.h)}function T(a,b){var c=b>>5;b%=32;for(var d=a.g.length-c,e=[],f=0;f<d;f++)e[f]=0<b?L(a,f+c)>>>b|L(a,f+c+1)<<32-b:L(a,f+c);return new F(e,a.h)};N(xb(J,32),J);N(xb(J,128),J);function yb(a){a&&"function"==typeof a.v&&a.v()};function U(){this.h=this.h;this.g=this.g}U.prototype.h=!1;U.prototype.v=function(){this.h||(this.h=!0,this.j())};U.prototype.j=function(){if(this.g)for(;this.g.length;)this.g.shift()()};var zb=!z||9<=Number(bb),Ab=!z||9<=Number(bb),Bb=z&&!y(Za,"9",function(){for(var a=0,b=ua(String(Ya)).split("."),c=ua("9").split("."),d=Math.max(b.length,c.length),e=0;0==a&&e<d;e++){var f=b[e]||"",g=c[e]||"";do{f=/(\d*)(\D*)(.*)/.exec(f)||["","","",""];g=/(\d*)(\D*)(.*)/.exec(g)||["","","",""];if(0==f[0].length&&0==g[0].length)break;a=Ca(0==f[1].length?0:parseInt(f[1],10),0==g[1].length?0:parseInt(g[1],10))||Ca(0==f[2].length,0==g[2].length)||Ca(f[2],g[2]);f=f[3];g=g[3]}while(0==a)}return 0<=a}),
Cb=function(){if(!l.addEventListener||!Object.defineProperty)return!1;var a=!1,b=Object.defineProperty({},"passive",{get:function(){a=!0}});try{l.addEventListener("test",la,b),l.removeEventListener("test",la,b)}catch(c){}return a}();function Db(a,b){this.type=a;this.g=this.target=b;this.defaultPrevented=!1}Db.prototype.h=function(){this.defaultPrevented=!0};function V(a,b){Db.call(this,a?a.type:"");this.relatedTarget=this.g=this.target=null;this.button=this.screenY=this.screenX=this.clientY=this.clientX=0;this.key="";this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1;this.state=null;this.pointerId=0;this.pointerType="";this.i=null;if(a){var c=this.type=a.type,d=a.changedTouches&&a.changedTouches.length?a.changedTouches[0]:null;this.target=a.target||a.srcElement;this.g=b;if(b=a.relatedTarget){if(Qa){a:{try{Ma(b.nodeName);var e=!0;break a}catch(f){}e=
!1}e||(b=null)}}else"mouseover"==c?b=a.fromElement:"mouseout"==c&&(b=a.toElement);this.relatedTarget=b;d?(this.clientX=void 0!==d.clientX?d.clientX:d.pageX,this.clientY=void 0!==d.clientY?d.clientY:d.pageY,this.screenX=d.screenX||0,this.screenY=d.screenY||0):(this.clientX=void 0!==a.clientX?a.clientX:a.pageX,this.clientY=void 0!==a.clientY?a.clientY:a.pageY,this.screenX=a.screenX||0,this.screenY=a.screenY||0);this.button=a.button;this.key=a.key||"";this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=
a.shiftKey;this.metaKey=a.metaKey;this.pointerId=a.pointerId||0;this.pointerType="string"===typeof a.pointerType?a.pointerType:Eb[a.pointerType]||"";this.state=a.state;this.i=a;a.defaultPrevented&&V.o.h.call(this)}}oa(V,Db);var Fb=[1,4,2],Eb={2:"touch",3:"pen",4:"mouse"};V.prototype.h=function(){V.o.h.call(this);var a=this.i;if(a.preventDefault)a.preventDefault();else if(a.returnValue=!1,Bb)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};var Gb="closure_listenable_"+(1E6*Math.random()|0);var Hb=0;function Ib(a,b,c,d,e){this.listener=a;this.g=null;this.src=b;this.type=c;this.capture=!!d;this.h=e;this.key=++Hb;this.m=this.s=!1}function Jb(a){a.m=!0;a.listener=null;a.g=null;a.src=null;a.h=null};function Kb(a){this.src=a;this.g={};this.h=0}Kb.prototype.add=function(a,b,c,d,e){var f=a.toString();a=this.g[f];a||(a=this.g[f]=[],this.h++);var g;a:{for(g=0;g<a.length;++g){var k=a[g];if(!k.m&&k.listener==b&&k.capture==!!d&&k.h==e)break a}g=-1}-1<g?(b=a[g],c||(b.s=!1)):(b=new Ib(b,this.src,f,!!d,e),b.s=c,a.push(b));return b};function Lb(a,b){var c=b.type;if(c in a.g){var d=a.g[c],e=qa(d,b),f;(f=0<=e)&&Array.prototype.splice.call(d,e,1);f&&(Jb(b),0==a.g[c].length&&(delete a.g[c],a.h--))}};var Mb="closure_lm_"+(1E6*Math.random()|0),Nb={},Ob=0;function Pb(a,b,c,d,e){if(d&&d.once)return Qb(a,b,c,d,e);if(Array.isArray(b)){for(var f=0;f<b.length;f++)Pb(a,b[f],c,d,e);return null}c=Rb(c);return a&&a[Gb]?a.g.add(String(b),c,!1,ma(d)?!!d.capture:!!d,e):Sb(a,b,c,!1,d,e)}
function Sb(a,b,c,d,e,f){if(!b)throw Error("Invalid event type");var g=ma(e)?!!e.capture:!!e,k=Tb(a);k||(a[Mb]=k=new Kb(a));c=k.add(b,c,d,g,f);if(c.g)return c;d=Ub();c.g=d;d.src=a;d.listener=c;if(a.addEventListener)Cb||(e=g),void 0===e&&(e=!1),a.addEventListener(b.toString(),d,e);else if(a.attachEvent)a.attachEvent(Vb(b.toString()),d);else if(a.addListener&&a.removeListener)a.addListener(d);else throw Error("addEventListener and attachEvent are unavailable.");Ob++;return c}
function Ub(){var a=Wb,b=Ab?function(c){return a.call(b.src,b.listener,c)}:function(c){c=a.call(b.src,b.listener,c);if(!c)return c};return b}function Qb(a,b,c,d,e){if(Array.isArray(b)){for(var f=0;f<b.length;f++)Qb(a,b[f],c,d,e);return null}c=Rb(c);return a&&a[Gb]?a.g.add(String(b),c,!0,ma(d)?!!d.capture:!!d,e):Sb(a,b,c,!0,d,e)}
function Xb(a){if("number"!==typeof a&&a&&!a.m){var b=a.src;if(b&&b[Gb])Lb(b.g,a);else{var c=a.type,d=a.g;b.removeEventListener?b.removeEventListener(c,d,a.capture):b.detachEvent?b.detachEvent(Vb(c),d):b.addListener&&b.removeListener&&b.removeListener(d);Ob--;(c=Tb(b))?(Lb(c,a),0==c.h&&(c.src=null,b[Mb]=null)):Jb(a)}}}function Vb(a){return a in Nb?Nb[a]:Nb[a]="on"+a}
function Yb(a,b,c,d){var e=!0;if(a=Tb(a))if(b=a.g[b.toString()])for(b=b.concat(),a=0;a<b.length;a++){var f=b[a];f&&f.capture==c&&!f.m&&(f=Zb(f,d),e=e&&!1!==f)}return e}function Zb(a,b){var c=a.listener,d=a.h||a.src;a.s&&Xb(a);return c.call(d,b)}
function Wb(a,b){if(a.m)return!0;if(!Ab){if(!b)a:{b=["window","event"];for(var c=l,d=0;d<b.length;d++)if(c=c[b[d]],null==c){b=null;break a}b=c}d=b;b=new V(d,this);c=!0;if(!(0>d.keyCode||void 0!=d.returnValue)){a:{var e=!1;if(0==d.keyCode)try{d.keyCode=-1;break a}catch(g){e=!0}if(e||void 0==d.returnValue)d.returnValue=!0}d=[];for(e=b.g;e;e=e.parentNode)d.push(e);a=a.type;for(e=d.length-1;0<=e;e--){b.g=d[e];var f=Yb(d[e],a,!0,b);c=c&&f}for(e=0;e<d.length;e++)b.g=d[e],f=Yb(d[e],a,!1,b),c=c&&f}return c}return Zb(a,
new V(b,this))}function Tb(a){a=a[Mb];return a instanceof Kb?a:null}var $b="__closure_events_fn_"+(1E9*Math.random()>>>0);function Rb(a){if("function"===typeof a)return a;a[$b]||(a[$b]=function(b){return a.handleEvent(b)});return a[$b]};function W(a){U.call(this);this.l=a;this.i={}}oa(W,U);var ac=[];function bc(a){ra(a.i,function(b,c){this.i.hasOwnProperty(c)&&Xb(b)},a);a.i={}}W.prototype.j=function(){W.o.j.call(this);bc(this)};W.prototype.handleEvent=function(){throw Error("EventHandler.handleEvent not implemented");};function cc(a){U.call(this);this.i=a||document.body;this.l=new W(this);a=na(yb,this.l);this.h?a():(this.g||(this.g=[]),this.g.push(a));a=this.l;var b=this.i,c=this.u,d="click";Array.isArray(d)||(d&&(ac[0]=d.toString()),d=ac);for(var e=0;e<d.length;e++){var f=Pb(b,d[e],c||a.handleEvent,!1,a.l||a);if(!f)break;a.i[f.key]=f}}h(cc,U);
cc.prototype.u=function(a){if(!(!(zb?0==a.i.button:"click"==a.type||a.i.button&Fb[0])||Sa&&a.ctrlKey||a.defaultPrevented))for(var b=a.target;b&&b!=this.i;){if(b.tagName&&"a"==b.tagName.toLowerCase()){var c=b.getAttribute("href")||b.getAttributeNS("http://www.w3.org/1999/xlink","href"),d=c;try{var e=rb(c)[3];var f;if(f="www.google.com"===pb(e,!0)){var g=rb(c)[5];f="/url"===pb(g,!0)}if(f){var k=sb(c,"q");d=k?k:sb(c,"url")}}catch(C){a:{var t=C;if(null!=t){var n=t.A;if(null!=n){C=n;break a}}if(t instanceof
TypeError){var R=n=new kb;R.l=B(t);hb(R);n.g="__noinit__";n.g=t;n.i(new TypeError(n));t=n}else R=n=new E,R.l=B(t),hb(R),n.g="__noinit__",n.g=t,n.i(Error(n)),t=n;C=t}if(!(C instanceof ib))throw C.h;}d=null!=d?d:"";if(c!=d){e=void 0;b={target:"_blank",noreferrer:!0};c=window;d instanceof q?f=d:(f="undefined"!=typeof d.href?d.href:String(d),f instanceof q||(f="object"==typeof f&&f.h?f.g():String(f),Fa.test(f)?f=new q(f,r):(f=String(f),f=f.replace(/(%0A|%0D)/g,""),f=(g=f.match(Ea))&&Da.test(g[1])?new q(f,
r):null)),f=f||Ha);d=b.target||d.target;g=[];for(e in b)switch(e){case "width":case "height":case "top":case "left":g.push(e+"="+b[e]);break;case "target":case "noopener":case "noreferrer":break;default:g.push(e+"="+(b[e]?1:0))}e=g.join(",");if((w("iPhone")&&!w("iPod")&&!w("iPad")||w("iPad")||w("iPod"))&&c.navigator&&c.navigator.standalone&&d&&"_self"!=d)e="A",g=document,e=String(e),"application/xhtml+xml"===g.contentType&&(e=e.toLowerCase()),g=e=g.createElement(e),f=f instanceof q?f:Ga(f),g.href=
u(f),e.setAttribute("target",d),b.noreferrer&&e.setAttribute("rel","noreferrer"),b=document.createEvent("MouseEvent"),b.initMouseEvent("click",!0,!0,c,1),e.dispatchEvent(b);else if(b.noreferrer){if(c=La("",c,d,e),b=u(f),c){Pa&&-1!=b.indexOf(";")&&(b="'"+b.replace(/'/g,"%27")+"'");c.opener=null;Ba.test(b)&&(-1!=b.indexOf("&")&&(b=b.replace(va,"&amp;")),-1!=b.indexOf("<")&&(b=b.replace(wa,"&lt;")),-1!=b.indexOf(">")&&(b=b.replace(xa,"&gt;")),-1!=b.indexOf('"')&&(b=b.replace(ya,"&quot;")),-1!=b.indexOf("'")&&
(b=b.replace(za,"&#39;")),-1!=b.indexOf("\x00")&&(b=b.replace(Aa,"&#0;")));b='<meta name="referrer" content="no-referrer"><meta http-equiv="refresh" content="0; url='+b+'">';if(void 0===m)if(d=null,(e=l.trustedTypes)&&e.createPolicy){try{d=e.createPolicy("goog#html",{createHTML:pa,createScript:pa,createScriptURL:pa})}catch(C){l.console&&l.console.error(C.message)}m=d}else m=d;b=(d=m)?d.createHTML(b):b;b=new x(b,null,Ka);(c=c.document)&&c.write&&(c.write(b instanceof x&&b.constructor===x?b.i:"type_error:SafeHtml"),
c.close())}}else(c=La(f,c,d,e))&&b.noopener&&(c.opener=null);a.h();break}}b=b.parentNode}};function dc(a){new cc(a)}var X=["DOCS_installLinkReferrerSanitizer"],Y=l;X[0]in Y||"undefined"==typeof Y.execScript||Y.execScript("var "+X[0]);for(var Z;X.length&&(Z=X.shift());)X.length||void 0===dc?Y[Z]&&Y[Z]!==Object.prototype[Z]?Y=Y[Z]:Y=Y[Z]={}:Y[Z]=dc;}).call(this);
</script><script type="text/javascript" nonce="">DOCS_installLinkReferrerSanitizer();</script></body></html>